﻿using System;
using System.Collections.Generic;
using System.Reflection;

namespace CodeAffinity.FormAbstraction
{
    /// <summary>
    /// keeps a copy of data classes as they exist when loading occurs
    /// </summary>
    public class LoadMementos : List<DataClassBase>
    {
        /// <summary>
        /// Get a DataClass base currently stored in this collection
        /// </summary>
        /// <param name="currentlyInspecting">the object that we want to check</param>
        /// <returns>the object as it was loaded</returns>
        public DataClassBase GetDataClass(DataClassBase currentlyInspecting)
        {
            int primaryValue = GetKeyValue(currentlyInspecting);
            DataClassBase rVal = GetLoadMementoByKey(primaryValue, currentlyInspecting);
            return rVal;
        }

        /// <summary>
        /// gets the value of the primary key 
        /// </summary>
        /// <param name="inputObject">the object to get a primary key value from</param>
        /// <returns>the primary key value</returns>
        private int GetKeyValue(DataClassBase inputObject)
        {
            int keyVal = -1;
            Type t = inputObject.GetType();
            PropertyInfo[] props = t.GetProperties();

            foreach (PropertyInfo prop in props)
            {
                object[] attrs = prop.GetCustomAttributes(false);

                try
                {
                    foreach (PrimaryKeyPropertyAttribute attr in attrs)
                    {
                        keyVal = (int)prop.GetValue(inputObject, null);
                        break;
                    }
                }
                catch (InvalidCastException ice)
                {
                    throw new NoPrimaryKeySet(ice);
                }
                if (keyVal != -1)
                    break;
            }

            return keyVal;
        }

        /// <summary>
        /// searches internal objects for a primary key value
        /// </summary>
        /// <param name="keyValue">key value to search for</param>
        /// <param name="objInpected">the object we are getting the memento for</param>
        /// <returns>data class as it existed when it was loaded</returns>
        private DataClassBase GetLoadMementoByKey(int keyValue, DataClassBase objInpected)
        {
            DataClassBase rDcb = null;
            foreach (DataClassBase dcb in this)
            {
                int thisKey = GetKeyValue(dcb);
                if (thisKey.Equals(keyValue) && objInpected.GetType().Equals(dcb.GetType()) && !thisKey.Equals(0))
                {
                    rDcb = dcb;
                    break;
                }
            }
            return rDcb;
        }

    }
}
